/**
 * 动画缓动函数类型
 */
export type EasingFunction = (t: number) => number;

/**
 * 预定义的缓动函数集合
 */
export const easing = {
  /** 线性缓动 */
  linear: (t: number): number => t,
  
  /** 缓入缓出 */
  ease_in_out: (t: number): number => {
    return t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2;
  },
  
  /** 弹跳效果 */
  bounce: (t: number): number => {
    const n1 = 7.5625;
    const d1 = 2.75;

    if (t < 1 / d1) {
      return n1 * t * t;
    } else if (t < 2 / d1) {
      return n1 * (t -= 1.5 / d1) * t + 0.75;
    } else if (t < 2.5 / d1) {
      return n1 * (t -= 2.25 / d1) * t + 0.9375;
    } else {
      return n1 * (t -= 2.625 / d1) * t + 0.984375;
    }
  }
};

/**
 * 组合缓动函数
 */
export function combineEasing(...easings: EasingFunction[]): EasingFunction {
  return (t: number) => {
    let result = t;
    for (const easingFn of easings) {
      result = easingFn(result);
    }
    return result;
  };
}

/**
 * 动画变换类型
 */
export type AnimationTransform<T> = (element: T, delta: number) => T;

/**
 * 动画配置选项
 */
export interface AnimationOptions {
  /** 动画持续时间（毫秒） */
  duration?: number;
  /** 是否重复动画 */
  repeat?: boolean;
  /** 缓动函数 */
  easing?: EasingFunction;
}

/**
 * 动画类，用于创建和管理元素的动画效果
 */
export class Animation<T> {
  private duration: number;
  private repeat: boolean;
  private easing: EasingFunction;
  private startTime: number | null = null;
  private pausedTime: number = 0;
  private isPaused: boolean = false;
  private animationId: number | null = null;
  private completeCallbacks: Array<() => void> = [];
  
  /**
   * 创建一个新的动画
   * @param duration 动画持续时间（毫秒）
   */
  constructor(duration: number) {
    this.duration = duration;
    this.repeat = false;
    this.easing = easing.linear;
  }
  
  /**
   * 设置动画重复播放
   */
  public setRepeat(repeat: boolean): this {
    this.repeat = repeat;
    return this;
  }
  
  /**
   * 设置动画缓动函数
   */
  public setEasing(easing: EasingFunction): this {
    this.easing = easing;
    return this;
  }
  
  /**
   * 启动动画
   */
  public start(element: T, transform: AnimationTransform<T>): this {
    if (this.isPaused) {
      this.isPaused = false;
      this.startTime = Date.now() - this.pausedTime;
    } else {
      this.startTime = Date.now();
      this.pausedTime = 0;
    }
    
    const animate = () => {
      if (this.startTime === null || this.isPaused) return;
      
      const currentTime = Date.now();
      const elapsed = currentTime - this.startTime;
      const progress = Math.min(elapsed / this.duration, 1);
      const easedProgress = this.easing(progress);
      
      // 应用变换
      transform(element, easedProgress);
      
      // 检查是否完成
      if (progress === 1) {
        if (this.repeat) {
          // 重新开始动画
          this.startTime = currentTime;
          this.animationId = requestAnimationFrame(animate);
        } else {
          // 触发完成回调
          this.completeCallbacks.forEach(callback => callback());
        }
      } else {
        this.animationId = requestAnimationFrame(animate);
      }
    };
    
    this.animationId = requestAnimationFrame(animate);
    return this;
  }
  
  /**
   * 暂停动画
   */
  public pause(): this {
    if (!this.isPaused && this.startTime !== null) {
      this.isPaused = true;
      this.pausedTime = Date.now() - this.startTime;
      if (this.animationId !== null) {
        cancelAnimationFrame(this.animationId);
        this.animationId = null;
      }
    }
    return this;
  }
  
  /**
   * 停止动画
   */
  public stop(): this {
    this.pause();
    this.startTime = null;
    this.pausedTime = 0;
    return this;
  }
  
  /**
   * 添加动画完成回调
   */
  public onComplete(callback: () => void): this {
    this.completeCallbacks.push(callback);
    return this;
  }
}

/**
 * 动画管理器，用于统一管理多个动画
 */
export class AnimationManager {
  private animations: Map<string, Animation<any>> = new Map();
  
  /**
   * 添加动画
   */
  public addAnimation<T>(id: string, animation: Animation<T>): this {
    this.animations.set(id, animation);
    return this;
  }
  
  /**
   * 获取动画
   */
  public getAnimation(id: string): Animation<any> | undefined {
    return this.animations.get(id);
  }
  
  /**
   * 移除动画
   */
  public removeAnimation(id: string): this {
    const animation = this.animations.get(id);
    if (animation) {
      animation.stop();
      this.animations.delete(id);
    }
    return this;
  }
  
  /**
   * 暂停所有动画
   */
  public pauseAll(): this {
    this.animations.forEach(animation => animation.pause());
    return this;
  }
  
  /**
   * 恢复所有动画
   */
  public resumeAll(): this {
    this.animations.forEach(animation => {
      if (animation instanceof Animation && typeof (animation as any).start === 'function') {
        // 注意：这里简化了恢复逻辑，实际恢复可能需要更多信息
      }
    });
    return this;
  }
  
  /**
   * 停止所有动画
   */
  public stopAll(): this {
    this.animations.forEach(animation => animation.stop());
    this.animations.clear();
    return this;
  }
}

/**
 * 创建一个动画实例
 * @param duration 动画持续时间（毫秒）
 */
export function createAnimation<T>(duration: number): Animation<T> {
  return new Animation<T>(duration);
}

/**
 * 创建一个弹跳缓动函数
 */
export function bounce(easing: EasingFunction): EasingFunction {
  // 直接定义内部的bounce缓动函数
  const bounceEasing: EasingFunction = (t: number): number => {
    const n1 = 7.5625;
    const d1 = 2.75;

    if (t < 1 / d1) {
      return n1 * t * t;
    } else if (t < 2 / d1) {
      return n1 * (t -= 1.5 / d1) * t + 0.75;
    } else if (t < 2.5 / d1) {
      return n1 * (t -= 2.25 / d1) * t + 0.9375;
    } else {
      return n1 * (t -= 2.625 / d1) * t + 0.984375;
    }
  };

  return combineEasing(easing, bounceEasing);
}

/**
 * 创建一个百分比变换函数
 */
export function percentage(delta: number): number {
  return delta * 100;
}